{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Tensorflow Timeline Analysis on Model Zoo Benchmark among different data types\n",
    "\n",
    "This jupyter notebook will help you evaluate performance benefits among different data types on the level of Tensorflow operations via several models from Intel Model Zoo. The notebook will show users a bar chart like the picture below for the Tensorflow operation level performance comparison. The red horizontal line represents the performance of Tensorflow operations from one data type as performance baseline, and the blue bars represent the speedup of Tensorflow operations by using other data type with oneDNN. The orange bars represent the speedup of Tensorflow operations by using other data type without oneDNN. Users should be able to see a good speedup for those operations accelerated by Intel DL Boost instructions. \n",
    "> NOTE : Users need to get Tensorflow timeline json files from other Jupyter notebooks like benchmark_date_types_perf_comparison\n",
    "  first to proceed this Jupyter notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images\\compared_tf_op_duration_ratio_bar_types.png\" width=\"700\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Get Platform Information "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ignore all warning messages\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from profiling.profile_utils import PlatformUtils\n",
    "plat_utils = PlatformUtils()\n",
    "plat_utils.dump_platform_info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Section 1 : Prerequisites"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install cxxfilt\n",
    "\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "pd.set_option('display.max_rows', 500)\n",
    "pd.set_option('display.max_columns', 500)\n",
    "pd.set_option('display.width', 1500)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## List out the Timeline folders"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, list out all Timeline folders from previous runs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "filenames= os.listdir (\".\") \n",
    "result = []\n",
    "keyword = \"Timeline\"\n",
    "for filename in filenames: \n",
    "    if os.path.isdir(os.path.join(os.path.abspath(\".\"), filename)): \n",
    "        if filename.find(keyword) != -1:\n",
    "                result.append(filename)\n",
    "result.sort()\n",
    "\n",
    "index =0 \n",
    "for folder in result:\n",
    "    print(\" %d : %s \" %(index, folder))\n",
    "    index+=1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Select a Timeline folder from previous runs\n",
    "#### ACTION: Please select one Timeline folder and change FdIndex accordingly"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# use the \"FD_INDEX\" environment variable value if it exists.\n",
    "import os\n",
    "env_fd_index=os.environ.get('FD_INDEX', '')\n",
    "if env_fd_index != '':\n",
    "    FdIndex= int(env_fd_index)\n",
    "else:\n",
    "    ## USER INPUT\n",
    "    FdIndex= int(input('Input a index number of a folder: '))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "List out all Timeline json files inside Timeline folder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "TimelineFd = result[FdIndex]\n",
    "print(TimelineFd)\n",
    "datafiles = [TimelineFd +os.sep+ x for x in os.listdir(TimelineFd) if '.json' == x[-5:]]\n",
    "print(datafiles)\n",
    "if len(datafiles) is 0:\n",
    "    print(\"ERROR! No json file in the selected folder. Please select other folder.\")\n",
    "elif len(datafiles) is 1:\n",
    "    print(\"WARNING! There is only 1 json file in the selected folder. Please select other folder to proceed Section 1.2.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='section_2'></a>\n",
    "# Section 2: Performance analysis between two different data types"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Section 2.1 : Analyze TF Timeline results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 1: Select  two TF timeline files with different data types for analysis"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### List out all timeline files in the selected folder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if len(datafiles) is 1:\n",
    "    print(\"ERROR! There is only 1 json file in the selected folder.\")\n",
    "    print(\"Please select other Timeline folder from beginnning to proceed Section 1.2.\")\n",
    "\n",
    "for i in range(len(datafiles)):\n",
    "    print(\" %d : %s \" %(i, datafiles[i]))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### ACTION: Please select one timeline file as a perfomance baseline and the other as a comparison target\n",
    "Please put the related index for your selected timeline file.  \n",
    "In general, fp32 data type should be the performance baseline."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# use the \"BASELINE_INDEX\" environment variable value if it exists.\n",
    "import os\n",
    "env_baseline_index=os.environ.get('BASELINE_INDEX', '')\n",
    "if env_baseline_index != '':\n",
    "    Baseline_Index= int(env_baseline_index)\n",
    "else:\n",
    "    ## USER INPUT\n",
    "    Baseline_Index= int(input('Input a index number of a Performance Baseline: '))\n",
    "\n",
    "# comparison target\n",
    "env_comparison_index=os.environ.get('COMPARISON_INDEX', '')\n",
    "if env_comparison_index != '':\n",
    "    Comparison_Index= int(env_comparison_index)\n",
    "else:\n",
    "    ## USER INPUT\n",
    "    Comparison_Index= int(input('Input a index number of a Performance Comparison: '))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### List out two selected timeline files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "selected_datafiles = []\n",
    "selected_datafiles.append(datafiles[Baseline_Index])\n",
    "selected_datafiles.append(datafiles[Comparison_Index])\n",
    "print(selected_datafiles)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Find the related oneDNN JITDUMP folder and Tensorflow Log file with oneDNN Verbose log"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from profiling.profile_utils import PerfPresenter\n",
    "perfp=PerfPresenter()\n",
    "\n",
    "tag0, tag1 = perfp.get_diff_from_csv_filenames(selected_datafiles[0],selected_datafiles[1])\n",
    "tags = []\n",
    "jitdumps_fd_path = []\n",
    "logs_path = []\n",
    "\n",
    "for tag in [tag0, tag1]:\n",
    "    # TEMP FIX\n",
    "    if tag == 'bf16':\n",
    "        tag = 'bfloat16'\n",
    "    if tag == 'f32':\n",
    "        tag = 'fp32'\n",
    "    JITDUMP_FD_PATH= TimelineFd + os.sep +'JITDUMP_'+ tag\n",
    "    if os.path.isdir(os.path.join(os.path.abspath(\".\"), JITDUMP_FD_PATH)):\n",
    "        logs = [JITDUMP_FD_PATH +os.sep+ x for x in os.listdir(JITDUMP_FD_PATH) if '.log.old' == x[-8:]]\n",
    "        LOG_PATH = logs[0]\n",
    "        jitdumps_fd_path.append(JITDUMP_FD_PATH)\n",
    "        logs_path.append(LOG_PATH)\n",
    "    tags.append(tag)\n",
    "print(tags)\n",
    "print(jitdumps_fd_path)\n",
    "print(logs_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 2: Parsing timeline results into CSV files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib agg\n",
    "from profiling.profile_utils import TFTimelinePresenter\n",
    "csvfiles=[]\n",
    "\n",
    "tfp = TFTimelinePresenter(True)\n",
    "for fn in selected_datafiles:\n",
    "    if fn.find('/'):\n",
    "        fn_nofd=fn.split('/')[1]\n",
    "    else:\n",
    "        fn_nofd=fn\n",
    "    tfile_name= fn_nofd.split('.')[0]\n",
    "    tfile_prefix = fn_nofd.split('_')[0]\n",
    "    tfile_postfix = fn_nofd.strip(tfile_prefix)[1:] \n",
    "    csvpath = TimelineFd +os.sep+tfile_name+'.csv'\n",
    "    print(csvpath)\n",
    "    csvfiles.append(csvpath)\n",
    "    timeline_pd = tfp.postprocess_timeline(tfp.read_timeline(fn))\n",
    "    timeline_pd = timeline_pd[timeline_pd['ph'] == 'X']\n",
    "    tfp.get_tf_ops_time(timeline_pd,fn,tfile_prefix)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 3: Pre-processing for the two CSV files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "\n",
    "csvarray=[]\n",
    "for csvf in csvfiles:\n",
    "    print(\"read into pandas :\",csvf)\n",
    "    a = pd.read_csv(csvf)\n",
    "    csvarray.append(a)\n",
    "\n",
    "a = csvarray[0]\n",
    "b = csvarray[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Find tags among CSV files\n",
    "tags=[]\n",
    "from profiling.profile_utils import PerfPresenter\n",
    "perfp=PerfPresenter()\n",
    "tag0, tag1 = perfp.get_diff_from_csv_filenames(csvfiles[0],csvfiles[1])\n",
    "tags = [tag0, tag1]\n",
    "print('tags : ',tags)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 4: Merge two CSV files and caculate the speedup accordingly\n",
    "Users can check column \"speedup\" for the speedup from bfloat16 or int8.  \n",
    "If the operation uses oneDNN for acceleration, the \"mkl_op\" column should be marked as \"True\". \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import pandas as pd\n",
    "fdir='merged'\n",
    "if not os.path.exists(fdir):\n",
    "    os.mkdir(fdir)\n",
    "\n",
    "fpaths=[]\n",
    "fpaths.append(fdir+os.sep+'merged.csv')\n",
    "fpaths.append(fdir+os.sep+'diff_'+tags[0]+'.csv')\n",
    "fpaths.append(fdir+os.sep+'diff_'+tags[1]+'.csv')\n",
    "merged=tfp.merge_two_csv_files_v2(fpaths, a, b, tags)\n",
    "merged"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The unique Tensorflow operations from the first csv/Timline file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "print(\"Operations are only in\", tags[0], \" run\")\n",
    "extra1 = pd.read_csv(fpaths[1])\n",
    "extra1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The unique Tensorflow operations from the second csv/Timline file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Operations are only in\", tags[1], \" run\")\n",
    "extra2 = pd.read_csv(fpaths[2])\n",
    "extra2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 5: Draw a bar chart for elapsed time of TF ops among two different data types\n",
    "The first diagram compares the elapsed time of operations among two different data types.  \n",
    "The second diagram shows the speedup of TF operations from comparison target.  \n",
    "The blue bar of second diagram is accelerated by oneDNN operation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "print(fpaths[0])\n",
    "tfp.plot_compare_bar_charts(fpaths[0], tags=tags)\n",
    "tfp.plot_compare_ratio_bar_charts(fpaths[0], tags=['','oneDNN ops'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 6: Draw pie charts for elapsed time of TF ops among different data types\n",
    "Users should be able to identify top hotspots from below pie charts among different data types.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> NOTE: Users could also compare elapsed time of TF ops among any two different TF timeline files.\n",
    "\n",
    "We will have following pie charts in sequence:\n",
    "1. the pie chart for elpased time of TF ops from stock TF or the first csv/Timeline file\n",
    "2. the pie chart for elpased time of unique TF ops from stock TF or the first csv/Timeline file\n",
    "3. the pie chart for elpased time of TF ops from Intel TF or the second csv/Timeline file\n",
    "4. the pie chart for elpased time of unique TF ops from Intel TF or the second csv/Timeline file\n",
    "5. the pie chart for elpased time of common TF ops among stock & Intel TF or two csv/Timeline files\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The pie chart for elapsed time of TF ops from the first csv/Timline file\n",
    "understand which TF operations spend most of time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tfp.plot_pie_chart(csvfiles[0], tags[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The pie chart for elapsed time of  unique TF operations from the first csv/Timline file\n",
    "understand if there is any unique TF operation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tfp.plot_pie_chart(fpaths[1], tags[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The pie chart for elapsed time of TF ops from the second csv/Timline file\n",
    "understand which TF operations spend most of time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tfp.plot_pie_chart(csvfiles[1], tags[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The pie chart for elapsed time of  unique TF operations from the second csv/Timline file\n",
    "understand if there is any unique TF operation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tfp.plot_pie_chart(fpaths[2], tags[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The pie chart for elapsed time of common TF ops among  two csv/Timline files\n",
    "understand top hotspots differences among two csv/Timeline files."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "tfp.plot_compare_pie_charts(fpaths[0], tags=tags)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='section_2_2'></a>\n",
    "## Section 2.2: Analyze oneDNN debug logs and JIT dumps\n",
    "\n",
    ">NOTE: Section 2.2 is only relevant if user had DNNL_VERBOSE or DNNL_JIT_DUMP enabled\n",
    "\n",
    "### Step 1: Parse related oneDNN Verbose logs\n",
    "\n",
    ">NOTE: Step 1-3 is only relevant if user had DNNL_VERBOSE enabled."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from profiling.profile_utils import oneDNNUtils, oneDNNLog\n",
    "onednn = oneDNNUtils()\n",
    "\n",
    "log1 = oneDNNLog()\n",
    "log1.load_log(logs_path[0])\n",
    "exec_data1 = log1.exec_data\n",
    "\n",
    "log2 = oneDNNLog()\n",
    "log2.load_log(logs_path[1])\n",
    "exec_data2 = log2.exec_data\n",
    "print(logs_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  Step 2:  Primitives Type Speedup from comparison target ( bfloat16 or int8)\n",
    "The digram below shows performance speedup from the comparison target data type such as VNNI, or BF16."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    " onednn.stats_comp('type', 'time',log2, log1, tags=tags)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 3:  Time breakdown for JIT kernel type"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "oneDNN uses just-in-time compilation (JIT) to generate optimal code for some functions based on input parameters and instruction set supported by the system.   \n",
    "Therefore, users can see different JIT kernel type among different CPU and GPU architectures.  \n",
    "For example, users can see avx_core_vnni JIT kernel if the workload uses VNNI instruction on Cascake Lake platform.  \n",
    "Users can also see different OCL kernels among different Intel GPU generations.  \n",
    "Moreover, users can identify the top hotspots of JIT kernel executions with this time breakdown.  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " Time breakdown of Baseline Data Type for JIT kernel type "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Time Breakdown of %s data type\" %(tags[0]))\n",
    "onednn.breakdown(exec_data1,\"jit\",\"time\")\n",
    "onednn.breakdown(exec_data1,\"type\",\"time\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " Time breakdown of Comparison Data Type for JIT kernel type "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Time Breakdown of %s data type\" %(tags[1]))\n",
    "onednn.breakdown(exec_data2,\"jit\",\"time\")\n",
    "onednn.breakdown(exec_data2,\"type\",\"time\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 4: Inspect JIT Kernel \n",
    "\n",
    ">NOTE: Step 4 is only relevant if user had DNNL_JIT_DUMP enabled\n",
    "\n",
    "In this section, we analyze dump JIT files of the comparison data type.    \n",
    "Users should be able to see the exact CPU instruction usage like VNNI or BF16 from those JIT Dump files."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('will inspect JIT codes from %s data type in %s '%(tags[1], jitdumps_fd_path[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### List out all JIT Dump Files with index number"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "filenames= os.listdir (jitdumps_fd_path[1]) \n",
    "result = []\n",
    "keyword = \".bin\"\n",
    "for filename in filenames: \n",
    "    #if os.path.isdir(os.path.join(os.path.abspath(\".\"), filename)): \n",
    "    if filename.find(keyword) != -1:\n",
    "        result.append(filename)\n",
    "result.sort()\n",
    "\n",
    "jit_fd_index =0 \n",
    "for folder in result:\n",
    "    print(\" %d : %s \" %(jit_fd_index, folder))\n",
    "    jit_fd_index+=1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### ACTION :  Pick a JIT Dump file by putting its index value below"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## USER INPUT\n",
    "FdIndex = 0 \n",
    "# use the \"FD_INDEX\" environment variable value if it exists.\n",
    "import os\n",
    "env_jit_fd_index=os.environ.get('JIT_FD_INDEX', '')\n",
    "if env_jit_fd_index != '':\n",
    "    FdIndex= int(env_jit_fd_index)\n",
    "else:\n",
    "    ## USER INPUT\n",
    "    if jit_fd_index > 0:\n",
    "        FdIndex= int(input('Input a index number of a JIT folder: '))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### export JIT Dump file to environment variable JITFILE  and also related ISA keyword to environment variable DNNL_ISA_KEYWORD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if FdIndex < len(result):\n",
    "    logfile = result[FdIndex]\n",
    "    os.environ[\"JITFILE\"] = jitdumps_fd_path[1]+os.sep+logfile\n",
    "    print(os.environ[\"JITFILE\"])\n",
    "if tags[1] == 'f32':\n",
    "    os.environ[\"DNNL_ISA_KEYWORD\"] = \"zmm\"\n",
    "elif tags[1] == 'int8':\n",
    "    os.environ[\"DNNL_ISA_KEYWORD\"] = \"vpdpbusd\"\n",
    "elif tags[1] == 'bf16' or tags[1] == 'bfloat16':\n",
    "    os.environ[\"DNNL_ISA_KEYWORD\"] ='vdpbf16ps|vcvtne2ps2bf16'\n",
    "    \n",
    "print(os.environ[\"DNNL_ISA_KEYWORD\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### disassembler JIT Dump file\n",
    "> NOTE: zmm register is introduced by AVX512 ISA.  \n",
    "Users should see usage of **zmm** register in AVX512 JIT dump files.  \n",
    "\n",
    "> NOTE: vpdpbusd is introduced by AVX512_VNNI ISA.  \n",
    "Users should see usage of **vpdpbusd** in AVX512_VNNI JIT dump files. \n",
    "\n",
    "> NOTE: **vdpbf16ps**, **vcvtne2ps2bf16**, and **vcvtneps2bf16** are introduced by AVX512_BF16 ISA.  \n",
    "Users should see usage of vdpbf16ps, vcvtne2ps2bf16 or vcvtneps2bf16 in AVX512_BF16 JIT dump files. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> NOTE: For disassembler vdpbf16ps, vcvtne2ps2bf16, and vcvtneps2bf16 instructions, users must use objdump with **v2.34** or above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!objdump -D -b binary -mi386:x86-64 $JITFILE | grep -E $DNNL_ISA_KEYWORD"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### (Optional)Step 5: move all results files into the selected Timeline folder\n",
    "By runing below codes, all results files will be moved to the selected Timeline folder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from profiling.profile_utils import CommonUtils\n",
    "utils = CommonUtils()\n",
    "import os\n",
    "import shutil\n",
    "import datetime\n",
    "\n",
    "# move png and csv results into Timeline folder    \n",
    "pattern_list = [ \"*.png\" , \"*.csv\"]\n",
    "current_path = os.getcwd()\n",
    "for pattern in pattern_list:\n",
    "    png_fds, png_fd_paths = utils.found_files_in_folder(pattern, current_path)\n",
    "    for fd_path in png_fd_paths:\n",
    "        shutil.move(fd_path,TimelineFd)\n",
    "\n",
    "# move pretrained model, logs, merged files into Timeline folder \n",
    "fd_name_list = ['pretrained','merged','logs']\n",
    "timeinfo = datetime.datetime.now().strftime(\"%Y-%m-%d_%H:%M\")\n",
    "for fd_name in fd_name_list:\n",
    "    if os.path.isdir(fd_name) == True:\n",
    "        target_fd = TimelineFd + os.sep+ fd_name+'_'+timeinfo\n",
    "        shutil.move(fd_name,target_fd)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "intel-tensorflow",
   "language": "python",
   "name": "intel-tensorflow"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
